package com.rtx.job;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rtx.api.quartz.job.BaseJob;
import com.rtx.edi.log.bean.EdiContentLog;
import com.rtx.edi.log.bean.EdiLog;
import com.rtx.edi.log.service.EdiLogService;
import com.rtx.edi.model.base.Constant;
import com.rtx.job.bean.po.EdiJobConfig;
import com.rtx.job.bean.po.EdiSql;
import com.rtx.job.handler.EdiJobHandler;
import com.rtx.job.service.EdiJobConfigService;
import com.rtx.job.service.EdiSqlService;
import com.rtx.model.emums.EnumDataType;
import com.rtx.wms.std.common.bean.WmsConstant;
import com.rtx.wms.std.common.service.CommonService;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * EID标准回传任务执行器
 */
@Component
@DisallowConcurrentExecution
public class EdiStdReturnJob implements BaseJob {

    private Logger logger = LoggerFactory.getLogger(EdiStdReturnJob.class);

    @Resource
    private EdiJobHandler ediJobHandler;

    @Resource
    private EdiJobConfigService ediJobConfigService;

    @Resource
    private EdiSqlService ediSqlService;

    @Resource
    private CommonService commonService;

    @Resource
    private EdiLogService ediLogService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        //获取定时任务名
        String jobName = context.getJobDetail().getKey().getName();
        //根据任务名获取任务配置
        EdiJobConfig jobConfig = getEdiJobConfig(jobName);
        if(jobConfig == null){
            logger.info("定时任务：{}未配置",jobName);
            return;
        }
        //获取sql
        List<EdiSql> ediSqlList = getEdiSql(jobConfig);
        //获取仓库
        List<String> whseidList = getWhseidList(jobConfig);
        for(String whseid : whseidList){
            //获取数据
            List<Map<String, Object>> maps = ediJobHandler.selectData(whseid, ediSqlList);
            for(Map<String, Object> map : maps){
                EdiLog log = new EdiLog();
                log.setLogno(IdUtil.getSnowflakeNextIdStr());
                //log.setLogkey();
                log.setEdiapiname(context.getJobDetail().getDescription());
                log.setStarttime(DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN));
                EdiContentLog ediContentLog = new EdiContentLog();
                try {
                    String requestJson = JSON.toJSONString(map);
                    String result = send(jobConfig,requestJson);
                    //日志
                    ediContentLog.setLogno(log.getLogno());
                    ediContentLog.setRequest(requestJson);
                    ediContentLog.setResponse(result);
                    //解析结果
                    Map<String, Object> resultMap = ediJobHandler.analysisResults(map, jobConfig.getResultTemplate(), result);
                    //更新结果
                    ediJobHandler.updateResult(whseid,resultMap,ediSqlList);
                } catch (HttpException e) {
                    logger.error("仓库：{}，任务：{}执行异常",whseid,jobName,e);
                    ediContentLog.setErrorexception(e.getMessage());
                }
                log.setEndtime(DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN));
                log.setEdiContentLog(ediContentLog);
                //添加日志
                addEdiLog(log);
            }
        }
    }

    /**
     * 添加日志
     * @param log 日志
     */
    private void addEdiLog(EdiLog log) {
        try {
            ediLogService.addlogandcontent(EnumDataType.DEFAULT_DATASOURCE_KEY.getValue(),log);
        } catch (Exception e) {
            logger.error("ediapi名称：{}，日志关键字段：{}，保存异常",log.getEdiapiname(),log.getLogkey(),e);
        }
    }

    /**
     * 获取任务运行仓库
     * @param jobConfig 任务配置
     * @return 任务运行仓库
     */
    private List<String> getWhseidList(EdiJobConfig jobConfig) {
        List<String> list = new ArrayList<>();
        /**仓库类型（1激活的仓库，2激活的仓库（不包含企业级），3指定仓库，4自定义仓库）
         * 1，2标准的激活仓库查询，select db_logid from pl_db where isactive=1
         * 3，指定仓库，指定的仓库写入warehouse，多个以,分隔
         * 4，自定义仓库，自定义查询sql语句写入warehouse
         */
        switch (jobConfig.getWarehouseType()) {
            case "1" :
                list = commonService.selectActiveWhseid(Constant.ENTERPRISE);
                break;
            case "2" :
                list = commonService.selectActiveWhseidNotEnterprise(Constant.ENTERPRISE);
                break;
            case "3" :
                list = Arrays.asList(jobConfig.getWarehouse().split(","));
                break;
            case "4" :
                list = (List<String>) commonService.executeSql(Constant.ENTERPRISE,jobConfig.getWarehouse());
                break;
            default:
                list = Arrays.asList(EnumDataType.DEFAULT_DATASOURCE_KEY.getValue());
        }
        return list;
    }

    /**
     * 获取任务执行sql
     * @param jobConfig 任务配置
     * @return 任务执行sql
     */
    private List<EdiSql> getEdiSql(EdiJobConfig jobConfig) {
        LambdaQueryWrapper<EdiSql> query = Wrappers.lambdaQuery();
        query.eq(EdiSql::getEdiJobConfigId,jobConfig.getId());
        return ediSqlService.selectEdiSql("ris_edi",query);
    }

    /**
     * 根据任务名获取任务配置
     * @param jobName 任务名
     * @return 任务配置
     */
    private EdiJobConfig getEdiJobConfig(String jobName){
        LambdaQueryWrapper<EdiJobConfig> query = Wrappers.lambdaQuery();
        query.eq(EdiJobConfig::getJobName,jobName);
        List<EdiJobConfig> configList = ediJobConfigService.selectEdiJobConfig("ris_edi", query);
        return CollectionUtils.isEmpty(configList) ? null : configList.get(0);
    }

    /**
     * 发送请求
     * @param jobConfig 任务配置
     * @param requestJson 请求json
     * @return 返回结果
     */
    private String send(EdiJobConfig jobConfig,String requestJson){
        String result = null;
        try {
            logger.info("请求url：{}，请求数据：{}",jobConfig.getTargetUrl(),requestJson);
            //发送数据
            HttpRequest httpRequest = HttpRequest
                    .post(jobConfig.getTargetUrl())
                    .body(requestJson)
                    .timeout(60000);
            result = httpRequest.execute().body();
            logger.info("请求url：{}，请求结果：{}",jobConfig.getTargetUrl(),result);
        } catch (Exception e) {
            logger.info("请求url：{}，请求异常",jobConfig.getTargetUrl(),e);
        }
        return result;
    }
}
